import { config, AppConfig, Environment } from './index';

/**
 * 配置工具类
 */
export class ConfigUtils {
  /**
   * 检查是否为开发环境
   */
  static isDevelopment(): boolean {
    return config.server.environment === 'development';
  }

  /**
   * 检查是否为生产环境
   */
  static isProduction(): boolean {
    return config.server.environment === 'production';
  }

  /**
   * 检查是否为测试环境
   */
  static isTest(): boolean {
    return config.server.environment === 'test';
  }

  /**
   * 获取当前环境
   */
  static getEnvironment(): Environment {
    return config.server.environment;
  }

  /**
   * 检查是否启用调试模式
   */
  static isDebugEnabled(): boolean {
    return process.env['DEBUG'] === 'true' || this.isDevelopment();
  }

  /**
   * 检查是否启用 Swagger 文档
   */
  static isSwaggerEnabled(): boolean {
    return process.env['ENABLE_SWAGGER'] === 'true' || this.isDevelopment();
  }

  /**
   * 获取 Swagger 文档路径
   */
  static getSwaggerPath(): string {
    return process.env['SWAGGER_PATH'] || '/api-docs';
  }

  /**
   * 获取密码加密轮数
   */
  static getBcryptRounds(): number {
    return parseInt(process.env['BCRYPT_ROUNDS'] || '12');
  }

  /**
   * 获取会话超时时间（秒）
   */
  static getSessionTimeout(): number {
    return parseInt(process.env['SESSION_TIMEOUT'] || '3600');
  }

  /**
   * 获取最大登录尝试次数
   */
  static getMaxLoginAttempts(): number {
    return parseInt(process.env['MAX_LOGIN_ATTEMPTS'] || '5');
  }

  /**
   * 获取登录锁定时间（分钟）
   */
  static getLoginLockoutTime(): number {
    return parseInt(process.env['LOGIN_LOCKOUT_TIME'] || '30');
  }

  /**
   * 获取限流配置
   */
  static getRateLimitConfig() {
    return {
      windowMs: parseInt(process.env['RATE_LIMIT_WINDOW_MS'] || '900000'), // 15分钟
      max: parseInt(process.env['RATE_LIMIT_MAX_REQUESTS'] || '100'),
    };
  }

  /**
   * 验证配置完整性
   */
  static validateConfig(): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];

    // 检查必需的环境变量
    const requiredEnvVars = [
      'DATABASE_URL',
      'JWT_SECRET',
    ];

    for (const envVar of requiredEnvVars) {
      if (!process.env[envVar]) {
        errors.push(`必需的环境变量 ${envVar} 未设置`);
      }
    }

    // 检查 JWT 密钥长度
    if (process.env['JWT_SECRET'] && process.env['JWT_SECRET'].length < 32) {
      errors.push('JWT_SECRET 必须至少32个字符长');
    }

    // 检查端口范围
    const port = parseInt(process.env['PORT'] || '3000');
    if (port < 1 || port > 65535) {
      errors.push('PORT 必须在1-65535范围内');
    }

    // 检查环境类型
    const env = process.env['NODE_ENV'];
    if (env && !['development', 'production', 'test'].includes(env)) {
      errors.push('NODE_ENV 必须是 development、production 或 test');
    }

    return {
      isValid: errors.length === 0,
      errors,
    };
  }

  /**
   * 获取配置摘要信息（用于日志记录）
   */
  static getConfigSummary(): Record<string, any> {
    return {
      environment: config.server.environment,
      port: config.server.port,
      host: config.server.host,
      database: {
        host: config.database.host,
        port: config.database.port,
        database: config.database.database,
      },
      jwt: {
        expiresIn: config.jwt.expiresIn,
        refreshExpiresIn: config.jwt.refreshExpiresIn,
      },
      log: {
        level: config.log.level,
        filename: config.log.filename,
      },
      upload: {
        maxSize: config.upload.maxSize,
        allowedTypes: config.upload.allowedTypes,
      },
      cache: {
        ttl: config.cache.ttl,
        checkPeriod: config.cache.checkPeriod,
      },
    };
  }

  /**
   * 获取敏感配置信息（用于调试，不包含密码等敏感信息）
   */
  static getSafeConfig(): Record<string, any> {
    const summary = this.getConfigSummary();
    
    // 移除敏感信息
    delete summary['database'].password;
    delete summary['jwt'].secret;
    delete summary['email']?.auth?.pass;

    return summary;
  }

  /**
   * 检查数据库连接配置
   */
  static validateDatabaseConfig(): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];

    try {
      const url = new URL(config.database.url);
      
      if (!url.hostname) {
        errors.push('数据库主机地址无效');
      }
      
      if (!url.pathname || url.pathname === '/') {
        errors.push('数据库名称无效');
      }
      
      if (!url.username) {
        errors.push('数据库用户名无效');
      }
      
    } catch (error) {
      errors.push('数据库URL格式无效');
    }

    return {
      isValid: errors.length === 0,
      errors,
    };
  }

  /**
   * 获取环境特定的配置覆盖
   */
  static getEnvironmentOverrides(): Partial<AppConfig> {
    switch (config.server.environment) {
      case 'development':
        return {
          log: {
            ...config.log,
            level: 'debug',
          },
        };
        
      case 'production':
        return {
          log: {
            ...config.log,
            level: 'warn',
          },
          server: {
            ...config.server,
            corsOrigin: config.server.corsOrigin.filter(origin => origin !== '*'),
          },
        };
        
      case 'test':
        return {
          log: {
            ...config.log,
            level: 'error',
          },
        };
        
      default:
        return {};
    }
  }
}

/**
 * 配置验证器
 */
export class ConfigValidator {
  /**
   * 验证所有配置
   */
  static validateAll(): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];

    // 验证基础配置
    const configValidation = ConfigUtils.validateConfig();
    errors.push(...configValidation.errors);

    // 验证数据库配置
    const dbValidation = ConfigUtils.validateDatabaseConfig();
    errors.push(...dbValidation.errors);

    return {
      isValid: errors.length === 0,
      errors,
    };
  }

  /**
   * 验证特定配置项
   */
  static validateConfigItem(key: string, value: any): { isValid: boolean; error?: string } {
    switch (key) {
      case 'PORT':
        const port = parseInt(value);
        if (isNaN(port) || port < 1 || port > 65535) {
          return { isValid: false, error: 'PORT 必须是1-65535之间的有效数字' };
        }
        break;

      case 'JWT_SECRET':
        if (!value || value.length < 32) {
          return { isValid: false, error: 'JWT_SECRET 必须至少32个字符长' };
        }
        break;

      case 'NODE_ENV':
        if (!['development', 'production', 'test'].includes(value)) {
          return { isValid: false, error: 'NODE_ENV 必须是 development、production 或 test' };
        }
        break;

      case 'DATABASE_URL':
        try {
          new URL(value);
        } catch {
          return { isValid: false, error: 'DATABASE_URL 格式无效' };
        }
        break;
    }

    return { isValid: true };
  }
}

export default ConfigUtils; 